﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Aim2.Weapon;
using Aim2.Weapon.Projectile;
using System.Collections;
using Aim2.Ennemy;

/// Test JanJ BG

namespace Aim2 {
    public class Player : AnimatedObject, IObjectContainer {
        public enum State {
            Idle,
            IdleToLeft,
            Left,
            LeftToIdle,
            IdleToRight,
            Right,
            RightToIdle
        }
        static Texture2D spriteTextureIdle;
        static Texture2D spriteTextureLeft;
        static Texture2D spriteTextureRight;

        bool firing;

        public static Player player;

        public static Texture2D CurrentSpriteTexture { get; set; }

        public List<Projectile> Projectiles { get; set; }
        Stack<AnimatedObject> ToRemove;
        Aim2.Weapon.Weapon currentWeapon;

        public static State PlayerState { get; set; }
        private State move;

        public int Score { get; set; }

        public Player(IObjectContainer owner) {
            this.owner = owner;
            Scale = 0.5f;
            Depth = 1f;
            frames = 6;
            framesPerSec = 18;
            speed = 5f;
            Rotation = 0f;

            Health = 100f;
            CollisionDamage = 1f;

            firing = false;
            Projectiles = new List<Projectile>();
            ToRemove = new Stack<AnimatedObject>();
            //currentWeapon = new LaserGun(this);
            currentWeapon = new SpikeGun(this);
            animatedSprite = new AnimatedSprite(this, frames, framesPerSec);
            animatedSprite.LoopReverse = true;
            player = this;
            PlayerState = State.Idle;

            CollisionManager.Instance.Register(this);
        }

        public override void Load(ContentManager Content, Viewport viewport) {
            spriteTextureIdle = Content.Load<Texture2D>("Textures/3x2_shipIdle");
            spriteTextureIdle.Name = "Textures/3x2_shipIdle";
            spriteTextureLeft = Content.Load<Texture2D>("Textures/3x2_shipLeft");
            spriteTextureLeft.Name = "Textures/3x2_shipLeft";
            spriteTextureRight = Content.Load<Texture2D>("Textures/3x2_shipRight");
            spriteTextureRight.Name = "Textures/3x2_shipRight";

            layout = spriteTextureIdle.Name.GetLayout();
            height = spriteTextureIdle.Height;
            width = spriteTextureIdle.Width;


            Position = new Vector2(viewport.Width / 2, viewport.Height / 2);
            new Fireball(Vector2.Zero, Vector2.Zero, 0, null).Load(Content, viewport);
            new Hexagon(Vector2.Zero, 0, 0, null).Load(Content, viewport);
            new Laser(Vector2.Zero, Vector2.Zero, 0, null).Load(Content, viewport);
            new LaserGun(null).Load(Content, viewport);
            new Spike(Vector2.Zero, Vector2.Zero, 0, null).Load(Content, viewport);
            new SpikeGun(null).Load(Content, viewport);

            CurrentSpriteTexture = spriteTextureIdle;
        }

        public void HandleInput(InputState input) {
            Vector2 p = Position;
            float temp_speed = speed;

            if(input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.A))
                animatedSprite.AddToTPF(0.01f);
            if (input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Z) && animatedSprite.GetTPF() > 0)
                animatedSprite.AddToTPF(-0.01f);

            if (input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Q))
                this.Scale += 0.1f;
            if (input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.S))
                this.Scale -= 0.1f;

            if (input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.W))
                Laser.s += 0.1f;
            if (input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.X))
                Laser.s -= 0.1f;

            if (input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.LeftShift)) {
                temp_speed *= 2;
            }

            if (input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Space)) {
                currentWeapon.Fire(new Vector2(0, -1), Aim2.Side.Player);
                firing = true;
                currentWeapon.animatedSprite.Frame = 0;
                Score = Score + Game.Random.Next(10, 100);
            }

            move = State.Idle;
            if (input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Left)) {
                p.X -= temp_speed;
                move = State.Left;
            }
            if (input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Right)) {
                p.X += temp_speed;
                move = State.Right;
            }

            switch (PlayerState) {
                case State.Idle:
                    if (move != State.Idle) {
                        if (move == State.Left) {
                            PlayerState = State.IdleToLeft;
                            CurrentSpriteTexture = spriteTextureLeft;
                        }
                        else {
                            PlayerState = State.IdleToRight;
                            CurrentSpriteTexture = spriteTextureRight;
                        }
                        animatedSprite.LoopReverse = false;
                        animatedSprite.Reversed = false;
                        animatedSprite.StopOnLastFrame = true;
                        animatedSprite.Frame = 0;
                    }
                    break;
                case State.Left:
                    if (move != State.Left) {
                        PlayerState = State.LeftToIdle;
                        animatedSprite.Reversed = true;
                        animatedSprite.Paused = false;
                        animatedSprite.StopOnLastFrame = true;
                    }
                    break;
                case State.Right:
                    if (move != State.Right) {
                        PlayerState = State.RightToIdle;
                        animatedSprite.Reversed = true;
                        animatedSprite.Paused = false;
                        animatedSprite.StopOnLastFrame = true;
                    }
                    break;
                case State.RightToIdle:
                    if (animatedSprite.OnLastFrame()) {
                        CurrentSpriteTexture = spriteTextureIdle;
                        animatedSprite.Reversed = false;
                        animatedSprite.LoopReverse = true;
                        animatedSprite.StopOnLastFrame = false;
                        PlayerState = State.Idle;
                    }
                    else if (move == State.Right) {
                        animatedSprite.Reversed = false;
                        PlayerState = State.IdleToRight;
                    }
                    break;
                case State.LeftToIdle:
                    if (animatedSprite.OnLastFrame()) {
                        CurrentSpriteTexture = spriteTextureIdle;
                        animatedSprite.Reversed = false;
                        animatedSprite.LoopReverse = true;
                        animatedSprite.StopOnLastFrame = false;
                        PlayerState = State.Idle;
                    }
                    else if (move == State.Left) {
                        animatedSprite.Reversed = false;
                        PlayerState = State.IdleToLeft;
                    }
                    break;
                case State.IdleToLeft:
                    if (animatedSprite.OnLastFrame()) {
                        PlayerState = State.Left;
                        animatedSprite.Paused = true;
                        animatedSprite.StopOnLastFrame = true;
                    }
                    else if (move != State.Left) {
                        animatedSprite.Reversed = true;
                        PlayerState = State.LeftToIdle;
                    }
                    break;
                case State.IdleToRight:
                    if (animatedSprite.OnLastFrame()) {
                        PlayerState = State.Right;
                        animatedSprite.Paused = true;
                        animatedSprite.StopOnLastFrame = true;
                    }
                    else if (move != State.Right) {
                        animatedSprite.Reversed = true;
                        PlayerState = State.RightToIdle;
                    }
                    break;
            }
            if(input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Up))
                p.Y -= temp_speed;
            if(input.CurrentKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Down))
                p.Y += temp_speed;

            

            this.Position = p;
        }

        public override void Update(float elapsed){
            animatedSprite.UpdateFrame(elapsed);
            currentWeapon.UpdateWeapon(elapsed);

            if (firing) {
                currentWeapon.Update(elapsed);
                if (currentWeapon.animatedSprite.OnLastFrame())
                    firing = false;
            }

            foreach (Projectile p in Projectiles) {
                p.Update(elapsed);
            }

            base.Update(elapsed);
        }

        public override void Draw(SpriteBatch spriteBatch) {
            base.Draw(spriteBatch);

            animatedSprite.DrawFrame(spriteBatch, Position, CurrentSpriteTexture);

            foreach (Projectile p in Projectiles)
                p.Draw(spriteBatch);
            if (firing) {
                currentWeapon.Draw(spriteBatch);
            }
        }

        public void AddToRemovalList(AnimatedObject a) {
            ToRemove.Push(a);
        }

        public void RemovePending() {
            AnimatedObject a;
            while (ToRemove.Count > 0) {
                a = ToRemove.Pop();
                Projectiles.Remove((Projectile)a);
            }
        }

        public IEnumerator<AnimatedObject> GetEnumerator() {
            yield return this;
            foreach (Projectile p in Projectiles)
                yield return p;
        }

        IEnumerator IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }

        public override Side Side() {
            return Aim2.Side.Player;
        }
    }
}
